package com.yxinsur.imc.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yxinsur.imc.business.domain.*;
import com.yxinsur.imc.business.enums.IsDeletedEnum;
import com.yxinsur.imc.business.excel.ContractExpenseRateTemplate;
import com.yxinsur.imc.business.excel.RateTemplate;
import com.yxinsur.imc.business.form.ContractExpenseDataForm;
import com.yxinsur.imc.business.form.ContractExpenseSearchForm;
import com.yxinsur.imc.business.mapper.*;
import com.yxinsur.imc.business.service.IImcContractExpenseRateService;
import com.yxinsur.imc.business.vo.ContractExpenseRateVo;
import com.yxinsur.imc.business.vo.ContractVo;
import com.yxinsur.imc.common.exception.BusinessException;
import com.yxinsur.imc.common.utils.DateUtils;
import com.yxinsur.imc.common.utils.SecurityUtils;
import com.yxinsur.imc.common.utils.StringUtils;
import com.yxinsur.imc.common.validator.Assert;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 协议-产品费率Service业务层处理
 *
 * @author imc
 * @date 2021-08-20
 */
@Service
public class ImcContractExpenseRateServiceImpl extends ServiceImpl<ImcContractExpenseRateMapper, ImcContractExpenseRate> implements IImcContractExpenseRateService {
    private static final Logger logger = LoggerFactory.getLogger(ImcContractExpenseRateServiceImpl.class);

    @Autowired
    private ImcContractExpenseRateMapper imcContractExpenseRateMapper;

    @Autowired
    private ImcContractExpenseMapper imcContractExpenseMapper;

    @Autowired
    private ImcContractInsMapper imcContractInsMapper;

    @Autowired
    private ImcInsSchemeMapper imcInsSchemeMapper;

    @Autowired
    private ImcContractMapper imcContractMapper;

    @Autowired
    private ImcRepoInsMapper imcRepoInsMapper;

    /**
     * 查询协议-产品费率
     *
     * @param id 协议-产品费率ID
     * @return 协议-产品费率
     */
    @Override
    public ContractExpenseRateVo selectImcContractExpenseRateById(Long id) {
        return imcContractExpenseRateMapper.selectImcContractExpenseRateById(id);
    }

    /**
     * 查询协议-产品费率列表
     *
     * @param contractExpenseSearchForm 协议-产品费率
     * @return 协议-产品费率
     */
    @Override
    public List<ImcContractExpenseRate> selectImcContractExpenseRateList(ContractExpenseSearchForm contractExpenseSearchForm) {

        return imcContractExpenseRateMapper.selectImcContractExpenseRateList(contractExpenseSearchForm);
    }

    /**
     * 新增协议-产品费率
     *
     * @param contractExpenseDataForm 协议-产品费率
     * @return 结果
     */
    @Override
    public int insertImcContractExpenseRate(ContractExpenseDataForm contractExpenseDataForm) {
        logger.info("新增协议产品费率，数据：{}", contractExpenseDataForm.toString());
        ImcContractExpenseRate imcContractExpenseRate = new ImcContractExpenseRate();
        BeanUtils.copyProperties(contractExpenseDataForm, imcContractExpenseRate);
        this.defaultValue(imcContractExpenseRate);
        imcContractExpenseRate.setCreateTime(DateUtils.getNowDate());
        imcContractExpenseRate.setCreateId(SecurityUtils.getUsername());
        imcContractExpenseRate.setTenantId(SecurityUtils.getTenantId());
        imcContractExpenseRate.setUpdateId(SecurityUtils.getUsername());
        imcContractExpenseRate.setUpdateTime(DateUtils.getNowDate());
        if (this.checkExsit(imcContractExpenseRate)) {
            throw new BusinessException("费率已存在（勿重复导入）；");
        }
        return imcContractExpenseRateMapper.insertImcContractExpenseRate(imcContractExpenseRate);
    }

    private void defaultValue(ImcContractExpenseRate imcContractExpenseRate) {
        //保障期间和领取年龄是否为空 如果为空默认1-99999
        //缴费频率类型如果为空 默认BCDE
        String chargeIntervalEnum = imcContractExpenseRate.getChargeIntervalEnum();
        if (StringUtils.isEmpty(chargeIntervalEnum)) {
            imcContractExpenseRate.setChargeIntervalEnum("B,C,D,E");
        }
        Integer coveragePeriodUpperValue = imcContractExpenseRate.getCoveragePeriodUpperValue();
        Integer coveragePeriodLowerValue = imcContractExpenseRate.getCoveragePeriodLowerValue();
        Integer pensionAgeLower = imcContractExpenseRate.getPensionAgeLower();
        Integer pensionAgeUpper = imcContractExpenseRate.getPensionAgeUpper();
        if (coveragePeriodLowerValue == null || coveragePeriodUpperValue == null) {
            imcContractExpenseRate.setCoveragePeriodLowerValue(1);
            imcContractExpenseRate.setCoveragePeriodUpperValue(99999);
        }
        if (pensionAgeLower == null || pensionAgeUpper == null) {
            imcContractExpenseRate.setPensionAgeLower(1);
            imcContractExpenseRate.setPensionAgeUpper(99999);
        }
    }

    /**
     * 修改协议-产品费率
     *
     * @param contractExpenseDataForm 协议-产品费率
     * @return 结果
     */
    @Override
    public int updateImcContractExpenseRate(ContractExpenseDataForm contractExpenseDataForm) {
        logger.info("修改协议产品费率，数据：{}", contractExpenseDataForm.toString());
        Assert.isNull(contractExpenseDataForm.getId(), "传参有误，ID不能为空");
        ImcContractExpenseRate imcContractExpenseRate = this.imcContractExpenseRateMapper.selectById(contractExpenseDataForm.getId());
        BeanUtils.copyProperties(contractExpenseDataForm, imcContractExpenseRate);
        this.defaultValue(imcContractExpenseRate);
        imcContractExpenseRate.setUpdateTime(DateUtils.getNowDate());
        imcContractExpenseRate.setUpdateId(SecurityUtils.getUsername());
        if (this.checkExsit(imcContractExpenseRate)) {
            throw new BusinessException("费率已存在（勿重复导入）；");
        }
        return imcContractExpenseRateMapper.updateImcContractExpenseRate(imcContractExpenseRate);
    }

    /**
     * 批量删除协议-产品费率
     *
     * @param ids 需要删除的协议-产品费率ID
     * @return 结果
     */
    @Override
    public int deleteImcContractExpenseRateByIds(Long[] ids) {
        int deleteCount = 0;
        for (Long id : ids) {
            ImcContractExpenseRate imcContractExpenseRate = new ImcContractExpenseRate();
            imcContractExpenseRate.setId(id);
            imcContractExpenseRate.setIsDeleted(String.valueOf(id));
            deleteCount += imcContractExpenseRateMapper.updateById(imcContractExpenseRate);
        }
        return deleteCount;
    }

    /**
     * 删除协议-产品费率信息
     *
     * @param id 协议-产品费率ID
     * @return 结果
     */
    @Override
    public int deleteImcContractExpenseRateById(String id) {
        return imcContractExpenseRateMapper.deleteImcContractExpenseRateById(id);
    }

    /**
     * 协议费率列表查询
     *
     * @param contractExpenseSearchForm
     * @return
     */
    @Override
    public List<ContractExpenseRateVo> selectContractExpenseRateVoList(ContractExpenseSearchForm contractExpenseSearchForm) {
        return imcContractExpenseRateMapper.selectContractExpenseRateVoList(contractExpenseSearchForm, SecurityUtils.getTenantId());
    }

    @Transactional
    @Override
    public String importExpenseRate(Long contractExpenseId, List<ContractExpenseRateTemplate> rateList) {
        logger.info("协议费率产品导入，数据：{}条",rateList.size());
        if(CollectionUtils.isEmpty(rateList)){
            throw new BusinessException("导入费率数据无有效数据");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        List<ContractExpenseRateTemplate> validList = new ArrayList<>();
        Date date = DateUtils.getNowDate();//操作时间
        for (ContractExpenseRateTemplate template : rateList) {
            if (template.getIndex() != null) {
                StringBuffer errorMsg = new StringBuffer();
                Long repoInsId = null;//险种产品库ID
                if (StringUtils.isBlank(template.getRiskCode())) {
                    errorMsg.append("险种代码不能为空；");
                } else {
                    //根据科目获得协议  供应商信息
                    ImcContractExpense imcContractExpense = imcContractExpenseMapper.selectById(contractExpenseId);
                    ContractVo contract = imcContractMapper.getImcContractById(imcContractExpense.getContractId());
                    ImcRepoIns insCode = imcRepoInsMapper.getImcRepoInsByInsCode(template.getRiskCode(), contract.getRepoSupplierId());
                    //判断险种是否在该协议下
                    QueryWrapper<ImcContractIns> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("contract_id",imcContractExpense.getContractId());
                    queryWrapper.eq("repo_ins_id",insCode.getId());
                    queryWrapper.eq("is_deleted",IsDeletedEnum.N.getCode());
                    List<ImcContractIns> insList = imcContractInsMapper.selectList(queryWrapper);
                    if (insList.size() == 0) {
                        errorMsg.append("协议下不存在此险种代码（" + template.getRiskCode() + "）；");
                    } else if (insList.size() == 1) {
                        repoInsId = insCode.getId();
                    } else {
                        errorMsg.append("产品库中险种内部代码异常：（" + template.getRiskCode() + "）；");
                    }
                }
                if (template.getRate() == null) {
                    errorMsg.append("费率不能为空；");
                }
                if(template.getStartDate()==null){
                    errorMsg.append("费率生效时间[起]不能为空");
                }
                //执行插入数据
                ImcContractExpenseRate rate = new ImcContractExpenseRate();
                BeanUtils.copyProperties(template, rate);
                //默认值处理
                this.defaultValue(rate);
                //方案处理
                if (StringUtils.isNotBlank(template.getInsSchemeValue())) {
                    QueryWrapper<ImcInsScheme> schemeQueryWrapper = new QueryWrapper<>();
                    schemeQueryWrapper.eq("repo_ins_id", repoInsId);
                    schemeQueryWrapper.eq("ins_scheme_value", template.getInsSchemeValue());
                    schemeQueryWrapper.eq("is_deleted", IsDeletedEnum.N.getCode());
                    schemeQueryWrapper.eq("tenant_id", SecurityUtils.getTenantId());
                    List<ImcInsScheme> schemeList = this.imcInsSchemeMapper.selectList(schemeQueryWrapper);
                    if (schemeList.size() == 0) {
                        errorMsg.append("方案（" + template.getInsSchemeValue() + "）不存在；");
                    } else if (schemeList.size() == 1) {
                        rate.setInsSchemeId(schemeList.get(0).getId());
                    } else {
                        errorMsg.append("方案（" + template.getInsSchemeValue() + "）在系统中配置有重复；");
                    }
                }
                rate.setRepoInsId(repoInsId);
                rate.setContractExpenseId(contractExpenseId);
                rate.setCreateTime(date);
                rate.setCreateId(SecurityUtils.getUsername());
                rate.setIsDeleted(IsDeletedEnum.N.getCode());
                rate.setTenantId(SecurityUtils.getTenantId());
                try {
                    //校验是否存在
                    if (this.checkExsit(rate)) {
                        errorMsg.append("费率已存在（勿重复导入）；");
                    } else {
                        this.imcContractExpenseRateMapper.insertImcContractExpenseRate(rate);
                    }
                    successNum++;
                } catch (Exception e) {
                    errorMsg.append("本条数据与已配置数据有交集或数据校验不通过；");
                }

                if (errorMsg.length() > 0) {
                    errorMsg.insert(0, "序号" + template.getIndex() + ":");
                    errorMsg.append("\n<br/>");
                    failureNum++;
                } else {
                    validList.add(template);
                }
                failureMsg.append(errorMsg);
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：\n<br/>");
            throw new BusinessException(failureMsg.toString());
        }
        return successMsg.append("恭喜您，数据已导入成功！共 " + successNum + " 条").toString();
    }

    //校验费率是否重复
    private boolean checkExsit(ImcContractExpenseRate rate) {
        QueryWrapper<ImcContractExpenseRate> checkWrapper = new QueryWrapper<>();
        checkWrapper.eq("repo_ins_id", rate.getRepoInsId());
        checkWrapper.eq("contract_expense_id", rate.getContractExpenseId());
        checkWrapper.eq("charge_period_lower_value", rate.getChargePeriodLowerValue());
        checkWrapper.eq("charge_period_upper_value", rate.getChargePeriodUpperValue());
        checkWrapper.eq("coverage_period_lower_value", rate.getCoveragePeriodLowerValue());
        checkWrapper.eq("coverage_period_upper_value", rate.getCoveragePeriodUpperValue());
        checkWrapper.eq("pension_age_lower", rate.getPensionAgeLower());
        checkWrapper.eq("pension_age_upper", rate.getPensionAgeUpper());
        checkWrapper.eq("pay_year_lower", rate.getPayYearLower());
        checkWrapper.eq("pay_year_upper", rate.getPayYearUpper());
        checkWrapper.eq("ins_scheme_id",rate.getInsSchemeId());
        checkWrapper.eq("charge_interval_enum", rate.getChargeIntervalEnum());
        checkWrapper.eq("factor1_value", rate.getFactor1Value());
        checkWrapper.eq("factor2_value", rate.getFactor2Value());
        checkWrapper.eq("factor3_value", rate.getFactor3Value());
        checkWrapper.eq("is_deleted", IsDeletedEnum.N.getCode());
        checkWrapper.eq("tenant_id", rate.getTenantId());
        List<ImcContractExpenseRate> list = this.imcContractExpenseRateMapper.selectList(checkWrapper);
        return list.size() > 0 ? true : false;
    }
}
